import logging

from django.core.exceptions import ValidationError
from django.db import connection

from app.model.cs_admins import CsAdmins
from app.service import shop, operation_log
from app.service.cashier_admin import get_next_job_num
from libs import common
from libs.auth import generate_password, jwt_encode
from libs.common import success, is_empty_str, error, get_ip, rand_str
from libs.db import DB
from libs.form import RawJsonForm

logger = logging.getLogger(__name__)


def login(request):
    form = RawJsonForm(request.body)
    username = form.get('username')
    if is_empty_str(username):
        return error('用户名不能为空')
    password = form.get('password')
    if is_empty_str(password):
        return error('密码不能为空')
    try:
        admin = CsAdmins.objects.get(username=username)
    except CsAdmins.DoesNotExist:
        return error('账号不存在')
    crypt_passwd = admin.password
    if crypt_passwd != generate_password(password, admin.salt):
        return error('密码错误')
    now = common.get_ts()
    admin.updated = now
    try:
        token = jwt_encode(admin.id, admin.shop_id)
        admin.token = token
        update_fields = ['token', 'updated']
        last_login_at = admin.last_login_at
        last_logout_at = admin.last_logout_at
        title = '登录'
        typ_id = 3
        # 只记录正常退出头一次的登录时间
        if last_login_at < last_logout_at:
            admin.last_login_at = now
            update_fields.append('last_login_at')
            title = '正常登录'
            typ_id = 1
        admin.save(update_fields=update_fields)
    except Exception as ex:
        print(ex)
        logger.error(ex)
        return error('登录失败请重试')
    with connection.cursor() as cursor:
        operation_log.save({
            'typ_id': typ_id,
            'title': title,
            'operator_id': admin.id,
            'operator': admin.username,
        }, request, cursor)
        shop_id = admin.shop_id
        db_shop = shop.get_shop_by_id(cursor, shop_id, ['shop_name', 'auth_good'])
        data = {
            'id': admin.id,
            'token': token,
            'shop_id': shop_id,
            'shop_name': db_shop.get('shop_name', ''),
            'username': admin.username,
            'cashier_id': admin.id,
            'job_num': admin.job_num,
            'role_id': admin.role_id,
            'auth_good': db_shop.get('auth_good', 0),
        }
    return success(data)


def login_v2(request):
    form = RawJsonForm(request.body)
    username = form.get('username')
    if is_empty_str(username):
        return error('用户名不能为空')
    password = form.get('password')
    if is_empty_str(password):
        return error('密码不能为空')
    try:
        admin = CsAdmins.objects.get(username=username)
    except CsAdmins.DoesNotExist:
        return error('账号不存在')
    crypt_passwd = admin.password
    if crypt_passwd != generate_password(password, admin.salt):
        return error('密码错误')
    admin_role_id = admin.role_id  # 1 店铺 2 仓库 3 管理员
    if admin_role_id in [0, 1]:
        device_code = form.get('device_code')
        if is_empty_str(device_code):
            return error('请提交设备码')
        if admin.device_code == '':
            db = DB('cs_admins')
            db.update({'device_code': device_code}, {'id': admin.id})
        elif admin.device_code != device_code:
            return error('该账号已绑定其它设备，无法登录当前设备')
    elif admin_role_id in [3, 4]:
        logger.info('admin_role_id', admin_role_id)
        pass
    else:
        return error('账号权限无效')
    now = common.get_ts()
    admin.updated = now
    try:
        token = jwt_encode(admin.id, admin.shop_id)
        admin.token = token
        update_fields = ['token', 'updated']
        last_login_at = admin.last_login_at
        last_logout_at = admin.last_logout_at
        title = '登录'
        typ_id = 3
        # 只记录正常退出头一次的登录时间
        if last_login_at < last_logout_at:
            admin.last_login_at = now
            update_fields.append('last_login_at')
            title = '正常登录'
            typ_id = 1
        admin.save(update_fields=update_fields)
    except Exception as ex:
        print(ex)
        logger.error(ex)
        return error('登录失败请重试')
    with connection.cursor() as cursor:
        operation_log.save({
            'typ_id': typ_id,
            'title': title,
            'operator_id': admin.id,
            'operator': admin.username,
        }, request, cursor)
    shop_id = admin.shop_id
    db_shop = shop.get_shop(shop_id, ['shop_name'])
    data = {
        'token': token,
        'shop_id': shop_id,
        'shop_name': db_shop.get('shop_name', ''),
        'username': admin.username,
        'cashier_id': admin.id,
        'job_num': admin.job_num,
    }
    return success(data)


def reg(request):
    now = common.get_ts()
    form = RawJsonForm(request.body)
    username = form.get('username')
    tel = form.get('tel')
    if is_empty_str(username):
        return error('用户名称不能为空')

    password = form.get('password')
    if is_empty_str(password):
        return error('密码不能为空')

    shop_id = form.get_int('shop_id')
    if shop_id <= 0:
        return error('无效的店铺ID')

    if shop_id is None:
        return error('店铺不存在')

    try:
        admin = CsAdmins()
        salt = rand_str(8, 1)
        admin.shop_id = shop_id
        admin.username = username
        admin.job_num = get_next_job_num(shop_id)
        admin.password = generate_password(password, salt)
        admin.salt = salt
        admin.avatar = ''
        admin.tel = tel
        admin.ip = get_ip(request)
        admin.status = 1
        token = jwt_encode(admin.id, shop_id)
        admin.token = token
        admin.created = now
        admin.updated = now
        admin.save()
    except ValidationError as e:
        msg_arr = []
        for (k, item) in e.message_dict.items():
            msg_arr.append('{}:{}'.format(k, ';'.join(item)))
        return error(';'.join(msg_arr))
    except Exception as ex:
        msg = ''
        if str(ex).index('(1062,') == 0:
            msg = '用户已存在'
        return error(msg)

    data = {"token": token}
    return success(data)
